package com.xhwl.logistics.util;

import com.xhwl.logistics.constant.VehicleConstant;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

public class AboutDateUtil {

    //该方法需要重新命名
    public static Date theSameDayOfDateAnother(Date date, String zone) {
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    public static Date theSameDayOfDate(Date date) {
        ZoneId zoneId = ZoneId.of(VehicleConstant.vehicleTimeZone);
        return Date.from(date.toInstant().atZone(zoneId).toLocalDate().atStartOfDay(zoneId).toInstant());
    }
    public static Date theNextDayOfDate(Date date, String zone) {
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        return Date.from(localDate.plusDays(1).atStartOfDay(zoneId).toInstant());
    }

    public static Date theFirstDayOfWeek(Date date, String zone) {
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        return Date.from(localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).atStartOfDay(zoneId).toInstant());
    }

    public static Date theSameDayHourOfDate(Date date, String zone) {
//        ZoneId zoneId = ZoneId.of(zone);
//
//        Instant instant = date.toInstant();
//        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
//        int minute = localDateTime.getMinute();
//        int second = localDateTime.getSecond();
//
//        long resultTime = date.getTime() - minute * 60 * 1000 - second * 1000;
//        return new Date(resultTime);
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
        return Date.from(localDateTime.withMinute(0).withSecond(0).withNano(0).atZone(zoneId).toInstant());
    }

    public static Date theSameMonthOfDate(Date date, String zone) {
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        int year = localDate.getYear();
        int month = localDate.getMonthValue();
        return Date.from(LocalDate.of(year, month, 1).atStartOfDay(zoneId).toInstant());
    }
    public static Date theSameMonthOfDate(Date date) {
        return theSameMonthOfDate(date, VehicleConstant.vehicleTimeZone);
    }
    public static Date theNextMonthOfDate(Date date, String zone) {
        ZoneId zoneId = ZoneId.of(zone);

        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        return Date.from(localDate.with(TemporalAdjusters.firstDayOfNextMonth()).atStartOfDay(zoneId).toInstant());
    }

    public static Date datePlusYear(Date date, int year) {
        ZoneId zoneId = ZoneId.of(VehicleConstant.vehicleTimeZone);
        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate().plusYears(year);
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    public static Date dateMinusYear(Date date, int year) {
        ZoneId zoneId = ZoneId.of(VehicleConstant.vehicleTimeZone);
        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate().minusYears(year);
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    public static Date datePlusMonth(Date date, int month) {
        ZoneId zoneId = ZoneId.of(VehicleConstant.vehicleTimeZone);
        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate().plusMonths(month);
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    public static Date dateMinusMonth(Date date, int month) {
        ZoneId zoneId = ZoneId.of(VehicleConstant.vehicleTimeZone);
        Instant instant = date.toInstant();
        LocalDate localDate = instant.atZone(zoneId).toLocalDate().minusMonths(month);
        return Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    public static Date datePlusDay(Date date, int day) {
        long time = date.getTime() + (long)day*24*3600*1000;
        return new Date(time);
    }
    public static Date dateMinusDay(Date date, int day) {
        long time = date.getTime() - (long)day*24*3600*1000;
        return new Date(time);
    }
    public static Date datePlusHour(Date date, int hour) {
        long time = date.getTime() + (long)hour*3600*1000;
        return new Date(time);
    }
    public static Date dateMinusHour(Date date, int hour) {
        long time = date.getTime() - (long)hour*3600*1000;
        return new Date(time);
    }

    public static LocalDate theSameDayOfDate(Date date, String zone) {
        Instant instant = date.toInstant();
        return instant.atZone(ZoneId.of(zone)).toLocalDate();
    }

    public static LocalDate localDatePlusDay(LocalDate localDate, int day) {
        return localDate.plusDays(day);
    }

    public static LocalDateTime localDatePlusTime(LocalDate localDate, int hour, int minute) {
        return localDate.atTime(hour, minute);
    }

    public static Date fromLocalDateTime(LocalDateTime localDateTime, String zone) {
        Instant instant = localDateTime.atZone(ZoneId.of(zone)).toInstant();
        return Date.from(instant);
    }

    public static Date overnightDate(Date date, String zone, int day, int hour, int minute) {
        LocalDate localDate = theSameDayOfDate(date, zone);
        LocalDateTime localDateTime = localDatePlusTime(localDatePlusDay(localDate, day), hour, minute);
        return fromLocalDateTime(localDateTime, zone);
    }

    public static Date stringToDate(String dateTimeString) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(VehicleConstant.vehicleDateTimeFormat);
        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, dateTimeFormatter);
        return Date.from(localDateTime.atZone(ZoneId.of(VehicleConstant.vehicleTimeZone)).toInstant());
    }

    /**
     * 将大华ICC的时间字符串转换为时间类型
     */
    public static Date stringToDateDaHuaICC(String dateTimeString) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(VehicleConstant.daHuaICCVehicleDateTimeFormat);
        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, dateTimeFormatter);
        return Date.from(localDateTime.atZone(ZoneId.of(VehicleConstant.vehicleTimeZone)).toInstant());
    }

    public static Date hourStringToDate(String dateTimeString) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(VehicleConstant.vehicleDateTimeFormat);

        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString + ":00:00", dateTimeFormatter);
        return Date.from(localDateTime.atZone(ZoneId.of(VehicleConstant.vehicleTimeZone)).toInstant());
        //sql使用DATE_FORMAT函数查询出的结果时间字串为%Y-%m，转成时间LocalDate时，字串需要"日"的信息，因此字串拼接"-01",作为"日"的信息
//        LocalDate localDate = LocalDate.parse(dateTimeString + ":00:00", dateTimeFormatter);
//        return Date.from(localDate.atStartOfDay(ZoneId.of(VehicleConstant.vehicleTimeZone)).toInstant());
    }

    public static String dateToString(Date date) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(VehicleConstant.vehicleDateTimeFormat);
        return dateTimeFormatter.format(ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of(VehicleConstant.vehicleTimeZone)));
    }

    public static String dateToString(Date date, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return dateTimeFormatter.format(ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of(VehicleConstant.vehicleTimeZone)));
    }

    public static String durationString(Date exitTime, Date enterTime) {
        if (null!=exitTime && null!=enterTime) {
            Duration duration = Duration.of(exitTime.getTime() - enterTime.getTime(), ChronoUnit.MILLIS);
            long days = duration.toDays();
            if (days != 0) {
                duration = duration.minusDays(days);
            }
            long hours = duration.toHours();
            if (hours != 0) {
                duration = duration.minusHours(hours);
            }
            long minutes = duration.toMinutes();
            if (minutes != 0) {
                duration = duration.minusMinutes(minutes);
            }
            long seconds = duration.getSeconds();
            return days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒";
        }
        return "/";
    }

    public static String durationString(Integer inputMinutes) {
        if (null!=inputMinutes) {
            Duration duration = Duration.ofMinutes(inputMinutes);
            long days = duration.toDays();
            if (days != 0) {
                duration = duration.minusDays(days);
            }
            long hours = duration.toHours();
            if (hours != 0) {
                duration = duration.minusHours(hours);
            }
            long minutes = duration.toMinutes();
            if (minutes != 0) {
                duration = duration.minusMinutes(minutes);
            }
            long seconds = duration.getSeconds();
            return days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒";
        }
        return "/";
    }

}
